package example1;

/**
 * <h3>designPattern</h3>
 * <p>延迟加载方式创建单例，传说中的懒汉式<p/>
 * <p>即在调用方第一次调用getInstance()时才初始化全局唯一实例</p>
 * @author : zhang.bw
 * @date : 2020-06-08 11:30
 **/
public class Singleton2 {
	// 静态字段引用唯一实例
	private static Singleton2 INSTANCE = null;

	/** 懒汉式 */
	// 实现方式：通过静态方法返回实例，即:外部调用方获得这个唯一实例
	// 优点：单例对象的生成是在应用需要使用单例对象才生成，可以提高应用的启用速度。
	// 缺点：不是线程安全的，如果多线程同时调用，会产生多个对象。
	public static Singleton2 getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new Singleton2();
		}
		return INSTANCE;
	}

	/** 懒汉式 + 同步锁方式 */
	// 实现方式：懒汉式单例模式的问题在于他是线程不安全的，那么我们加上线程保护机制，问题不就解决了吗？
	// 懒汉式同步锁就是在方法上加上同步锁机制，确保线程安全。
	// 优点：同懒汉式
	// 缺点：加锁synchronized会影响并发性能
	/*public synchronized static Singleton2 getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new Singleton2();
		}
		return INSTANCE;
	}*/


	/** 懒汉式 + 双重检查方式 */
	// 实现方式：懒汉式同步锁可以解决线程安全问题，但是我们在获取单例对象时有必要每次都判断线程同步锁吗？
	// 如果单例对象已经不为空了，我们直接返回单例对象就可以了，双重校验方式是在同步锁的基础上再加上一层单例对象是否为
	// 空判断，以减少判断线程同步锁的次数，从而提高效率。
	// 优点：懒加载、线程安全、效率高
	// 缺点：代码复杂
	/*public static Singleton2 getInstance() {
		if (INSTANCE == null) {
			synchronized (Singleton2.class) {
				if (INSTANCE == null) {
					INSTANCE = new Singleton2();
				}
			}
		}
		return INSTANCE;
	}*/

	// 私有构造方法，保证外部无法实例化
	private Singleton2() {
	}
}
